<template>
  <div class="flex-column" :style="{ 'height': height, 'width': width }">
    <div v-if="tableOptions.header" class="flex-alignc-justifyb table-header">
      <div class="flex-alignc">
        <slot name="header-left">
        </slot>
      </div>
      <div v-if="tableOptions.headerRight" class="flex-alignc">
        <slot name="header-right">
        </slot>
        <el-button v-if="tableOptions.download" type="warning" plain icon="Download" circle title="导出" @click="handleExport"></el-button>
        <el-button v-if="tableOptions.refresh" plain icon="Refresh" circle title="刷新" @click="getTableData" />
      </div>
    </div>

    <div class="flex-alignc">
      <div class="mb10" v-if="tableOptions.tableEvent && tableOptions.tableEvent.length">
        <template v-for="(item, index) in tableOptions.tableEvent" :key="index">
          <el-button type="primary" @click="item.callback()">{{ item.label || item.title }}</el-button>
        </template>
      </div>
      <slot name="custom-event">
      </slot>
    </div>
    
<!-- basic-table-tpl -->
    <el-table class="flex1 " :data="tableData" :class="className" >
      <template v-for="(item,index) in tableOptions.column" :key="index">
        <!-- 表格配置列 -->
        <template v-if="item.prop">
          <el-table-column v-if="item.prop=='$index'" type="index" :width="item.width?item.width:'50'" v-bind="item.attrs"></el-table-column>
          <el-table-column v-else-if="item.prop=='$selection'" type="selection" :width="item.width?item.width:'50'" v-bind="item.attrs"></el-table-column>
          <el-table-column v-else :prop="item.prop" :label="item.label" :width="item.width" v-bind="item.attrs">
            <template #default="scope">
              <slot :name="item.prop" :row="scope.row" :$index="scope.$index">
                {{ (scope.row[item.prop]+'').length?(item.formatter?item.formatter(scope.row):scope.row[item.prop]):(item.default?item.default:'--') }}
                <!-- <div v-if="(scope.row[item.prop]+'').length">
                  {{ item.formatter?item.formatter(scope.row[item.prop]):scope.row[item.prop] }}
                </div>
                <div v-else>{{ item.default?item.default:'--' }}</div> -->
                <!-- {{ scope.row[item.prop]?scope.row[item.prop]:item.default }} -->
              </slot>
            </template>
          </el-table-column>
        </template>
        <!-- 表格操作按钮 -->
        <template v-else-if="!item.prop&&item.type=='operation'">
          <el-table-column :label="item.label?item.label:'操作'" :width="item.width?item.width:'50'" v-bind="item.attrs">
            <template #default="scope">
              <slot name="operation-prepend" :row="scope.row" :$index="scope.$index">
              </slot>
              <template v-for="(eventItem, eventIndex) in tableOptions.rowEvent" :key="eventIndex">
                <el-button type="primary" link @click="eventItem.callback(scope.row, eventItem)" :disabled="buttonDisable(scope.row, eventItem)">
                  {{ eventItem.formatter?eventItem.formatter(scope.row):(eventItem.label || eventItem.title) }}
                </el-button>
              </template>
              <slot name="operation-append" :row="scope.row" :$index="scope.$index">
              </slot>
            </template>
          </el-table-column>
        </template>
      </template>
      <template #empty>
        <el-empty description="暂无数据" />
      </template>
    </el-table>

    <pagination
      v-show="tableOptions.page&&page.total > 0"
      :total="page.total"
      v-model:page="page.page"
      v-model:limit="page.size"
      @pagination="getTableData"
    />
  </div>
</template>

<script setup>
const { proxy } = getCurrentInstance()
import request from '@/utils/request'

const props = defineProps({
  // 表格类名
  className: {
    type: String,
    default: ''
  },
  // 表格宽度
  width: {
    type: String,
    default: '100%'
  },
  // 表格高度
  height: {
    type: String,
    default: '100%'
  },
  // 分页配置
  page: {
    type: Object,
    default: () => ({
      page: 1,
      size: 10,
      total: 0,
    }),
  },
  // 表格数据
  data: {
    type: Object,
    default: () => ([]),
  },
  // 表格配置
  options: {
    type: Object,
    default: () => ({}),
  },
})

watch(() => props.data, (val) => {
  tableData.value = val
}, {
  deep: true
})

// 表格配置项
const tableOptions = computed(() => {
  return {
    page:true, // 分页
    header:true,
    headerRight:true,
    refresh:true, // 表格刷新
    download:false, // 表格导出
    downloadUrl:'', // 表格导出接口
    downloadName:'', // 表格导出文件名称
    initRequest:true, // 初始化时接口是否自动请求数据,防止初始化时接口参数异步赋值为空,赋值后手动调用initTable方法请求数据
    ...props.options
  }
})

// 分页数据
// const page = ref({
//   page: 1,
//   size: 10,
//   total: 0,
// });
// 加载状态
const loading = ref(true);
// 表格数据
const tableData = ref([]);

// 获取表格数据
const getTableData = () => {
  if(!tableOptions.value.tableRequest?.url) return
  loading.value = true
  tableData.value = []
  let requestObj = JSON.parse(JSON.stringify(tableOptions.value.tableRequest))
  requestObj[requestObj.method=='get'?'params':'data'].page = props.page.page
  requestObj[requestObj.method=='get'?'params':'data'].size = props.page.size
  request(requestObj).then(res => {
    tableData.value = res.data.list
    if(res.data.totalCount) {
      props.page.total = Number(res.data.totalCount)
    }
  })
}

// 初始化表格数据
const initTable = () => {
  props.page.page = 1
  getTableData();
}

// 导出
const handleExport = () => {
  if(!tableOptions.value.downloadUrl) return
  proxy.download(tableOptions.value.downloadUrl, {
    page:props.page.page,
    size:props.page.size,
    ...tableOptions.value.tableRequest.data,
  },`${tableOptions.value.downloadName}_${proxy.parseTime(new Date(), "{y}-{m}-{d} {h}-{i}-{s}")}.xlsx`,{
    transformRequest:undefined,
    headers: { 'Content-Type': 'application/json;charset=utf-8' }
  })
}


// 操作按钮按钮的diable的处理方法
const buttonDisable = (row, item) => {
  if (
    row &&
    JSON.stringify(row) !== "{}" &&
    item &&
    item.disabled &&
    typeof item.disabled == "function"
  ) {
    // const _disabled = await
    return item.disabled(row);
  } else if (
    row &&
    JSON.stringify(row) !== "{}" &&
    item &&
    item.disabled &&
    typeof item.disabled == "boolean"
  ) {
    // const _disabled = await
    return item.disabled;
  } else {
    return false;
  }
};

onMounted(() => {
  if(tableOptions.value.initRequest) {
    getTableData()
  }
});

// 对外暴露初始化方法
defineExpose({
  initTable,
  getTableData
});
</script>

<style scoped lang="scss">
.table-header {
  height: 48px;
}
</style>
